/*
 *  Copyright (c) 2006-2007 Tiark Rompf, Nachtlicht-Media
 *  
 *  All rights reserved. This software is copyrighted work licensed under
 *  the terms of the MIT License.  Please consult the file "LICENSE" for
 *  details. There is NO warranty.
 *  
 *  $Id:$
 */

/**
* program	: glutmech V1.1
* author	: Simon Parkinson-Bates.
* E-mail	: sapb@yallara.cs.rmit.edu.au
* Copyright Simon Parkinson-Bates.
* "source if freely avaliable to anyone to copy as long as they
*  acknowledge me in their work."
*
* Funtional features 
* ------------------
* * online menu system avaliable by pressing left mouse button
* * online cascading help system avaliable, providing information on
*	the several  key strokes and what they do.
* * animation sequence coded which makes the mech walk through an
*	environment.  Shadows will soon be added to make it look
*	more realistic.
* * menu control to view mech in wireframe or sold mode.
* * various key strokes avaliable to control idependently the mechs
*	many joints.
* * various key strokes avaliable to view mech and environment from 
*	different angles
* * various key strokes avaliable to alter positioning of the single
*	light source.
*
*
* Program features
* ----------------
* * uses double buffering
* * uses display lists
* * uses glut to manage windows, callbacks, and online menu.
* * uses gl.glpolygonfill() to maintain colors in wireframe and solid
*	mode.
*
**/



import java.util.concurrent.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.media.opengl.*;
import javax.media.opengl.glu.*;
import com.sun.opengl.util.*;




public class TestMech
{


/* start of compilation conditions */
static final boolean SPHERE = true;
static final boolean COLOR = true;
static final boolean LIGHT = true;
static final boolean TORSO = true;
static final boolean HIP = true;
static final boolean SHOULDER = true;
static final boolean UPPER_ARM = true;
static final boolean LOWER_ARM = true;
static final boolean ROCKET_POD = true;
static final boolean UPPER_LEG = true;
static final boolean LOWER_LEG = true;
static final boolean NO_NORM = true;
static final boolean ANIMATION = true;
static final boolean DRAW_MECH = true;
static final boolean DRAW_ENVIRO = true;
static final boolean MOVE_LIGHT = true;
/* end of compilation conditions */

/* start various header files needed */

/* #include <stdlib.h> */
/* #include <math.h> */
static final boolean GLUT = true;
static final boolean GLUT_KEY = true;
static final boolean GLUT_SPEC = true;
/* #include <GLUT/glut.h> */

/* end of header files */

/* start of display list definitions */
static final int SOLID_MECH_TORSO = 1;
static final int SOLID_MECH_HIP = 2;
static final int SOLID_MECH_SHOULDER = 3;
static final int SOLID_MECH_UPPER_ARM = 4;
static final int SOLID_MECH_FOREARM = 5;
static final int SOLID_MECH_UPPER_LEG = 6;
static final int SOLID_MECH_FOOT = 7;
static final int SOLID_MECH_ROCKET = 8;
static final int SOLID_MECH_VULCAN = 9;
static final int SOLID_ENVIRO = 10;
/* end of display list definitions */

/* start of motion rate variables */
static final int ANKLE_RATE = 3;
static final int HEEL_RATE = 3;
static final int ROTATE_RATE = 10;
static final int TILT_RATE = 10;
static final int ELBOW_RATE = 2;
static final int SHOULDER_RATE = 5;
static final int LAT_RATE = 5;
static final int CANNON_RATE = 40;
static final int UPPER_LEG_RATE = 3;
static final int UPPER_LEG_RATE_GROIN = 10;
static final int LIGHT_TURN_RATE = 10;
static final int VIEW_TURN_RATE = 10;
/* end of motion rate variables */

/* start of motion  variables */

/* Some <math.h> files do not define M_PI... */
static final float M_PI = 3.14159265358979323846f;

GL gl;
GLU glu;
GLUT glut;


GLUquadric qobj;

char leg = 0;

float shoulder1 = 0, shoulder2 = 0, shoulder3 = 0, shoulder4 = 0, lat1 = 20, lat2 = 20,
  elbow1 = 0, elbow2 = 0, pivot = 0, tilt = 10, ankle1 = 0, ankle2 = 0, heel1 = 0,
  heel2 = 0, hip11 = 0, hip12 = 10, hip21 = 0, hip22 = 10, fire = 0, solid_part = 0,
  anim = 0, turn = 0, turn1 = 0, lightturn = 0, lightturn1 = 0;

float elevation = 0.0f, distance = 0.0f, frame = 3.0f
 /* foot1v[] = {} foot2v[] = {} */ ;

/* end of motion variables */

/* start of material definitions */
///if (LIGHT)
///{
float mat_specular[] =
{0.628281f, 0.555802f, 0.366065f, 1.0f};
float mat_ambient[] =
{0.24725f, 0.1995f, 0.0745f, 1.0f};
float mat_diffuse[] =
{0.75164f, 0.60648f, 0.22648f, 1.0f};
float mat_shininess[] =
{128.0f * 0.4f};

float mat_specular2[] =
{0.508273f, 0.508273f, 0.508373f};
float mat_ambient2[] =
{0.19225f, 0.19225f, 0.19225f};
float mat_diffuse2[] =
{0.50754f, 0.50754f, 0.50754f};
float mat_shininess2[] =
{128.0f * 0.6f};

float mat_specular3[] =
{0.296648f, 0.296648f, 0.296648f};
float mat_ambient3[] =
{0.25f, 0.20725f, 0.20725f};
float mat_diffuse3[] =
{1, 0.829f, 0.829f};
float mat_shininess3[] =
{128.0f * 0.088f};

float mat_specular4[] =
{0.633f, 0.727811f, 0.633f};
float mat_ambient4[] =
{0.0215f, 0.1745f, 0.0215f};
float mat_diffuse4[] =
{0.07568f, 0.61424f, 0.07568f};
float mat_shininess4[] =
{128 * 0.6f};

float mat_specular5[] =
{0.60f, 0.60f, 0.50f};
float mat_ambient5[] =
{0.0f, 0.0f, 0.0f};
float mat_diffuse5[] =
{0.5f, 0.5f, 0.0f};
float mat_shininess5[] =
{128.0f * 0.25f};

///}
/* end of material definitions */

/* start of the body motion functions */
public void
Heel1Add()
{
  heel1 = (heel1 + HEEL_RATE) % 360;
}

public void
Heel1Subtract()
{
  heel1 = (heel1 - HEEL_RATE) % 360;
}

public void
Heel2Add()
{
  heel2 = (heel2 + HEEL_RATE) % 360;
}

public void
Heel2Subtract()
{
  heel2 = (heel2 - HEEL_RATE) % 360;
}

public void
Ankle1Add()
{
  ankle1 = (ankle1 + ANKLE_RATE) % 360;
}

public void
Ankle1Subtract()
{
  ankle1 = (ankle1 - ANKLE_RATE) % 360;
}

public void
Ankle2Add()
{
  ankle2 = (ankle2 + ANKLE_RATE) % 360;
}

public void
Ankle2Subtract()
{
  ankle2 = (ankle2 - ANKLE_RATE) % 360;
}

public void
RotateAdd()
{
  pivot = (pivot + ROTATE_RATE) % 360;
}

public void
RotateSubtract()
{
  pivot = (pivot - ROTATE_RATE) % 360;
}

public void
MechTiltSubtract()
{
  tilt = (tilt - TILT_RATE) % 360;
}

public void
MechTiltAdd()
{
  tilt = (tilt + TILT_RATE) % 360;
}

public void
elbow1Add()
{
  elbow1 = (elbow1 + ELBOW_RATE) % 360;
}

public void
elbow1Subtract()
{
  elbow1 = (elbow1 - ELBOW_RATE) % 360;
}

public void
elbow2Add()
{
  elbow2 = (elbow2 + ELBOW_RATE) % 360;
}

public void
elbow2Subtract()
{
  elbow2 = (elbow2 - ELBOW_RATE) % 360;
}

public void
shoulder1Add()
{
  shoulder1 = (shoulder1 + SHOULDER_RATE) % 360;
}

public void
shoulder1Subtract()
{
  shoulder1 = (shoulder1 - SHOULDER_RATE) % 360;
}

public void
shoulder2Add()
{
  shoulder2 = (shoulder2 + SHOULDER_RATE) % 360;
}

public void
shoulder2Subtract()
{
  shoulder2 = (shoulder2 - SHOULDER_RATE) % 360;
}

public void
shoulder3Add()
{
  shoulder3 = (shoulder3 + SHOULDER_RATE) % 360;
}

public void
shoulder3Subtract()
{
  shoulder3 = (shoulder3 - SHOULDER_RATE) % 360;
}

public void
shoulder4Add()
{
  shoulder4 = (shoulder4 + SHOULDER_RATE) % 360;
}

public void
shoulder4Subtract()
{
  shoulder4 = (shoulder4 - SHOULDER_RATE) % 360;
}

public void
lat1Raise()
{
  lat1 = (lat1 + LAT_RATE) % 360;
}

public void
lat1Lower()
{
  lat1 = (lat1 - LAT_RATE) % 360;
}

public void
lat2Raise()
{
  lat2 = (lat2 + LAT_RATE) % 360;
}

public void
lat2Lower()
{
  lat2 = (lat2 - LAT_RATE) % 360;
}

public void
FireCannon()
{
  fire = (fire + CANNON_RATE) % 360;
}

public void
RaiseLeg1Forward()
{
  hip11 = (hip11 + UPPER_LEG_RATE) % 360;
}

public void
LowerLeg1Backwards()
{
  hip11 = (hip11 - UPPER_LEG_RATE) % 360;
}

public void
RaiseLeg1Outwards()
{
  hip12 = (hip12 + UPPER_LEG_RATE_GROIN) % 360;
}

public void
LowerLeg1Inwards()
{
  hip12 = (hip12 - UPPER_LEG_RATE_GROIN) % 360;
}

public void
RaiseLeg2Forward()
{
  hip21 = (hip21 + UPPER_LEG_RATE) % 360;
}

public void
LowerLeg2Backwards()
{
  hip21 = (hip21 - UPPER_LEG_RATE) % 360;
}

public void
RaiseLeg2Outwards()
{
  hip22 = (hip22 + UPPER_LEG_RATE_GROIN) % 360;
}

public void
LowerLeg2Inwards()
{
  hip22 = (hip22 - UPPER_LEG_RATE_GROIN) % 360;
}

/* end of body motion functions */

/* start of light source position functions */
public void
TurnRight()
{
  turn = (turn - VIEW_TURN_RATE) % 360;
}

public void
TurnLeft()
{
  turn = (turn + VIEW_TURN_RATE) % 360;
}

public void
TurnForwards()
{
  turn1 = (turn1 - VIEW_TURN_RATE) % 360;
}

public void
TurnBackwards()
{
  turn1 = (turn1 + VIEW_TURN_RATE) % 360;
}

public void
LightTurnRight()
{
  lightturn = (lightturn + LIGHT_TURN_RATE) % 360;
}

public void
LightTurnLeft()
{
  lightturn = (lightturn - LIGHT_TURN_RATE) % 360;
}

public void
LightForwards()
{
  lightturn1 = (lightturn1 + LIGHT_TURN_RATE) % 360;
}

public void
LightBackwards()
{
  lightturn1 = (lightturn1 - LIGHT_TURN_RATE) % 360;
}

/* end of light source position functions */

/* start of geometric shape functions */
void
Box(float width, float height, float depth, boolean solid)
{
  char i, j = 0;
  float x = width / 2.0f, y = height / 2.0f, z = depth / 2.0f;

  for (i = 0; i < 4; i++) {
    gl.glRotatef(90.0f, 0.0f, 0.0f, 1.0f);
    if (j != 0) {
      if (!solid)
        gl.glBegin(GL.GL_LINE_LOOP);
      else
        gl.glBegin(GL.GL_QUADS);
      gl.glNormal3f(-1.0f, 0.0f, 0.0f);
      gl.glVertex3f(-x, y, z);
      gl.glVertex3f(-x, -y, z);
      gl.glVertex3f(-x, -y, -z);
      gl.glVertex3f(-x, y, -z);
      gl.glEnd();
      if (solid) {
        gl.glBegin(GL.GL_TRIANGLES);
        gl.glNormal3f(0.0f, 0.0f, 1.0f);
        gl.glVertex3f(0.0f, 0.0f, z);
        gl.glVertex3f(-x, y, z);
        gl.glVertex3f(-x, -y, z);
        gl.glNormal3f(0.0f, 0.0f, -1.0f);
        gl.glVertex3f(0.0f, 0.0f, -z);
        gl.glVertex3f(-x, -y, -z);
        gl.glVertex3f(-x, y, -z);
        gl.glEnd();
      }
      j = 0;
    } else {
      if (!solid)
        gl.glBegin(GL.GL_LINE_LOOP);
      else
        gl.glBegin(GL.GL_QUADS);
      gl.glNormal3f(-1.0f, 0.0f, 0.0f);
      gl.glVertex3f(-y, x, z);
      gl.glVertex3f(-y, -x, z);
      gl.glVertex3f(-y, -x, -z);
      gl.glVertex3f(-y, x, -z);
      gl.glEnd();
      if (solid) {
        gl.glBegin(GL.GL_TRIANGLES);
        gl.glNormal3f(0.0f, 0.0f, 1.0f);
        gl.glVertex3f(0.0f, 0.0f, z);
        gl.glVertex3f(-y, x, z);
        gl.glVertex3f(-y, -x, z);
        gl.glNormal3f(0.0f, 0.0f, -1.0f);
        gl.glVertex3f(0.0f, 0.0f, -z);
        gl.glVertex3f(-y, -x, -z);
        gl.glVertex3f(-y, x, -z);
        gl.glEnd();
      }
      j = 1;
    }
  }
}

void
Octagon(float side, float height, boolean solid)
{
  char j;
  float x = (float)Math.sin(0.785398163f) * side, y = side / 2.0f, z = height / 2.0f, c;

  c = x + y;
  for (j = 0; j < 8; j++) {
    gl.glTranslatef(-c, 0.0f, 0.0f);
    if (!solid)
      gl.glBegin(GL.GL_LINE_LOOP);
    else
      gl.glBegin(GL.GL_QUADS);
    gl.glNormal3f(-1.0f, 0.0f, 0.0f);
    gl.glVertex3f(0.0f, -y, z);
    gl.glVertex3f(0.0f, y, z);
    gl.glVertex3f(0.0f, y, -z);
    gl.glVertex3f(0.0f, -y, -z);
    gl.glEnd();
    gl.glTranslatef(c, 0.0f, 0.0f);
    if (solid) {
      gl.glBegin(GL.GL_TRIANGLES);
      gl.glNormal3f(0.0f, 0.0f, 1.0f);
      gl.glVertex3f(0.0f, 0.0f, z);
      gl.glVertex3f(-c, -y, z);
      gl.glVertex3f(-c, y, z);
      gl.glNormal3f(0.0f, 0.0f, -1.0f);
      gl.glVertex3f(0.0f, 0.0f, -z);
      gl.glVertex3f(-c, y, -z);
      gl.glVertex3f(-c, -y, -z);
      gl.glEnd();
    }
    gl.glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
  }
}

/* end of geometric shape functions */
///if (NORM)
///{
void
Normalize(float v[])
{
  float d = (float)Math.sqrt(v[1] * v[1] + v[2] * v[2] + v[3] * v[3]);

  if (d == 0.0f) {
    System.out.println("zero length vector");
    return;
  }
  v[1] /= d;
  v[2] /= d;
  v[3] /= d;
}

void
NormXprod(float v1[], float v2[], float v[], float out[])
{
  int i, j;
  float length;

  out[0] = v1[1] * v2[2] - v1[2] * v2[1];
  out[1] = v1[2] * v2[0] - v1[0] * v2[2];
  out[2] = v1[0] * v2[1] - v1[1] * v2[0];
  Normalize(out);
}

///}

void
SetMaterial(float spec[], float amb[], float diff[], float shin[])
{

  gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, spec, 0);
  gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, shin, 0);
  gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, amb, 0);
  gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, diff, 0);
}

void
MechTorso(boolean solid)
{
  gl.glNewList(SOLID_MECH_TORSO, GL.GL_COMPILE);
if (LIGHT)
{
  SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess);
}
  gl.glColor3f(1.0f, 1.0f, 0.0f);
  Box(1.0f, 1.0f, 3.0f, solid);
  gl.glTranslatef(0.75f, 0.0f, 0.0f);
if (LIGHT)
{
  SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2);
}
  gl.glColor3f(0.5f, 0.5f, 0.5f);
  Box(0.5f, 0.6f, 2.0f, solid);
  gl.glTranslatef(-1.5f, 0.0f, 0.0f);
  Box(0.5f, 0.6f, 2.0f, solid);
  gl.glTranslatef(0.75f, 0.0f, 0.0f);
  gl.glEndList();
}

void
MechHip(boolean solid)
{
  int i;

  gl.glNewList(SOLID_MECH_HIP, GL.GL_COMPILE);
if (LIGHT)
{
  SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess);
}
  gl.glColor3f(1.0f, 1.0f, 0.0f);
  Octagon(0.7f, 0.5f, solid);
if (SPHERE)
{
  for (i = 0; i < 2; i++) {
    if (i != 0)
      gl.glScalef(-1.0f, 1.0f, 1.0f);
    gl.glTranslatef(1.0f, 0.0f, 0.0f);
if (LIGHT)
{
    SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2);
}
    gl.glColor3f(0.5f, 0.5f, 0.5f);
    if (!solid)
      glu.gluQuadricDrawStyle(qobj, GLU.GLU_LINE);
    glu.gluSphere(qobj, 0.2f, 16, 16);
    gl.glTranslatef(-1.0f, 0.0f, 0.0f);
  }
  gl.glScalef(-1.0f, 1.0f, 1.0f);
}
  gl.glEndList();
}

void
Shoulder(boolean solid)
{
  gl.glNewList(SOLID_MECH_SHOULDER, GL.GL_COMPILE);
if (LIGHT)
{
  SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess);
}
  gl.glColor3f(1.0f, 1.0f, 0.0f);
  Box(1.0f, 0.5f, 0.5f, solid);
  gl.glTranslatef(0.9f, 0.0f, 0.0f);
if (LIGHT)
{
  SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2);
}
  gl.glColor3f(0.5f, 0.5f, 0.5f);
if (SPHERE)
{
  if (!solid)
    glu.gluQuadricDrawStyle(qobj, GLU.GLU_LINE);
  glu.gluSphere(qobj, 0.6f, 16, 16);
}
  gl.glTranslatef(-0.9f, 0.0f, 0.0f);
  gl.glEndList();
}

void
UpperArm(boolean solid)
{
  int i;

  gl.glNewList(SOLID_MECH_UPPER_ARM, GL.GL_COMPILE);
if (LIGHT)
{
  SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess);
}
  gl.glColor3f(1.0f, 1.0f, 0.0f);
  Box(1.0f, 2.0f, 1.0f, solid);
  gl.glTranslatef(0.0f, -0.95f, 0.0f);
  gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
if (LIGHT)
{
  SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2);
}
  gl.glColor3f(0.5f, 0.5f, 0.5f);
  if (!solid)
    glu.gluQuadricDrawStyle(qobj, GLU.GLU_LINE);
  glu.gluCylinder(qobj, 0.4f, 0.4f, 1.5f, 16, 10);
if (LIGHT)
{
  SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess);
}
  gl.glColor3f(1.0f, 1.0f, 0.0f);
  gl.glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
  gl.glTranslatef(-0.4f, -1.85f, 0.0f);
  gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
  for (i = 0; i < 2; i++) {
    if (!solid)
      glu.gluQuadricDrawStyle(qobj, GLU.GLU_LINE);
    if (i != 0)
      glu.gluCylinder(qobj, 0.5f, 0.5f, 0.8f, 16, 10);
    else
      glu.gluCylinder(qobj, 0.2f, 0.2f, 0.8f, 16, 10);
  }
  for (i = 0; i < 2; i++) {
    if (i != 0)
      gl.glScalef(-1.0f, 1.0f, 1.0f);
    if (!solid)
      glu.gluQuadricDrawStyle(qobj, GLU.GLU_LINE);
    if (i != 0)
      gl.glTranslatef(0.0f, 0.0f, 0.8f);
    glu.gluDisk(qobj, 0.2f, 0.5f, 16, 10);
    if (i != 0)
      gl.glTranslatef(0.0f, 0.0f, -0.8f);
  }
  gl.glScalef(-1.0f, 1.0f, 1.0f);
  gl.glRotatef(-90.0f, 0.0f, 1.0f, 0.0f);
  gl.glTranslatef(0.4f, 2.9f, 0.0f);
  gl.glEndList();
}

void
VulcanGun(boolean solid)
{
  int i;

  gl.glNewList(SOLID_MECH_VULCAN, GL.GL_COMPILE);

if (LIGHT)
{
  SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2);
}
  gl.glColor3f(0.5f, 0.5f, 0.5f);

  if (!solid) {
    glu.gluQuadricDrawStyle(qobj, GLU.GLU_LINE);
  }
  glu.gluCylinder(qobj, 0.5f, 0.5f, 0.5f, 16, 10);
  gl.glTranslatef(0.0f, 0.0f, 0.5f);
  glu.gluDisk(qobj, 0.0f, 0.5f, 16, 10);

  for (i = 0; i < 5; i++) {
    gl.glRotatef(72.0f, 0.0f, 0.0f, 1.0f);
    gl.glTranslatef(0.0f, 0.3f, 0.0f);
    if (!solid) {
      glu.gluQuadricDrawStyle(qobj, GLU.GLU_LINE);
    }
    glu.gluCylinder(qobj, 0.15f, 0.15f, 2.0f, 16, 10);
    glu.gluCylinder(qobj, 0.06f, 0.06f, 2.0f, 16, 10);
    gl.glTranslatef(0.0f, 0.0f, 2.0f);
    glu.gluDisk(qobj, 0.1f, 0.15f, 16, 10);
    glu.gluCylinder(qobj, 0.1f, 0.1f, 0.1f, 16, 5);
    gl.glTranslatef(0.0f, 0.0f, 0.1f);
    glu.gluDisk(qobj, 0.06f, 0.1f, 16, 5);
    gl.glTranslatef(0.0f, -0.3f, -2.1f);
  }
  gl.glEndList();
}

void
ForeArm(boolean solid)
{
  char i;

  gl.glNewList(SOLID_MECH_FOREARM, GL.GL_COMPILE);
if (LIGHT)
{
  SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess);
}
  gl.glColor3f(1.0f, 1.0f, 0.0f);
  for (i = 0; i < 5; i++) {
    gl.glTranslatef(0.0f, -0.1f, -0.15f);
    Box(0.6f, 0.8f, 0.2f, solid);
    gl.glTranslatef(0.0f, 0.1f, -0.15f);
    Box(0.4f, 0.6f, 0.1f, solid);
  }
  gl.glTranslatef(0.0f, 0.0f, 2.45f);
  Box(1.0f, 1.0f, 2.0f, solid);
  gl.glTranslatef(0.0f, 0.0f, -1.0f);
  gl.glEndList();
}

void
UpperLeg(boolean solid)
{
  int i;

  gl.glNewList(SOLID_MECH_UPPER_LEG, GL.GL_COMPILE);
if (LIGHT)
{
  SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess);
}
  gl.glColor3f(1.0f, 1.0f, 0.0f);
  if (!solid) {
    glu.gluQuadricDrawStyle(qobj, GLU.GLU_LINE);
  }
  gl.glTranslatef(0.0f, -1.0f, 0.0f);
  Box(0.4f, 1.0f, 0.7f, solid);
  gl.glTranslatef(0.0f, -0.65f, 0.0f);
  for (i = 0; i < 5; i++) {
    Box(1.2f, 0.3f, 1.2f, solid);
    gl.glTranslatef(0.0f, -0.2f, 0.0f);
    Box(1.0f, 0.1f, 1.0f, solid);
    gl.glTranslatef(0.0f, -0.2f, 0.0f);
  }
  gl.glTranslatef(0.0f, -0.15f, -0.4f);
  Box(2.0f, 0.5f, 2.0f, solid);
  gl.glTranslatef(0.0f, -0.3f, -0.2f);
  gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
if (LIGHT)
{
  SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2);
}
  gl.glColor3f(0.5f, 0.5f, 0.5f);
  glu.gluCylinder(qobj, 0.6f, 0.6f, 3.0f, 16, 10);
if (LIGHT)
{
  SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess);
}
  gl.glColor3f(1.0f, 1.0f, 0.0f);
  gl.glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
  gl.glTranslatef(0.0f, -1.5f, 1.0f);
  Box(1.5f, 3.0f, 0.5f, solid);
  gl.glTranslatef(0.0f, -1.75f, -0.8f);
  Box(2.0f, 0.5f, 2.0f, solid);
  gl.glTranslatef(0.0f, -0.9f, -0.85f);
if (LIGHT)
{
  SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2);
}
  gl.glColor3f(0.5f, 0.5f, 0.5f);
  glu.gluCylinder(qobj, 0.8f, 0.8f, 1.8f, 16, 10);
  for (i = 0; i < 2; i++) {
    if (i != 0)
      gl.glScalef(-1.0f, 1.0f, 1.0f);
    if (!solid)
      glu.gluQuadricDrawStyle(qobj, GLU.GLU_LINE);
    if (i != 0)
      gl.glTranslatef(0.0f, 0.0f, 1.8f);
    glu.gluDisk(qobj, 0.0f, 0.8f, 16, 10);
    if (i != 0)
      gl.glTranslatef(0.0f, 0.0f, -1.8f);
  }
  gl.glScalef(-1.0f, 1.0f, 1.0f);
  gl.glEndList();
}

void
Foot(boolean solid)
{

  gl.glNewList(SOLID_MECH_FOOT, GL.GL_COMPILE);
if (LIGHT)
{
  SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2);
}
  gl.glColor3f(0.5f, 0.5f, 0.5f);
  gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
  Octagon(1.5f, 0.6f, solid);
  gl.glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
  gl.glEndList();
}

void
LowerLeg(boolean solid)
{
  float k, l;

if (LIGHT)
{
  SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess);
}
  gl.glColor3f(1.0f, 1.0f, 0.0f);
  for (k = 0.0f; k < 2.0f; k++) {
    for (l = 0.0f; l < 2.0f; l++) {
      gl.glPushMatrix();
      gl.glTranslatef(k, 0.0f, l);
if (LIGHT)
{
      SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess);
}
      gl.glColor3f(1.0f, 1.0f, 0.0f);
      Box(1.0f, 0.5f, 1.0f, solid);
      gl.glTranslatef(0.0f, -0.45f, 0.0f);
if (LIGHT)
{
      SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2);
}
      gl.glColor3f(0.5f, 0.5f, 0.5f);
if (SPHERE)
{
      if (!solid)
        glut.glutWireSphere(0.2f, 16, 10);
      else
        glut.glutSolidSphere(0.2f, 16, 10);
}
      if (leg != 0)
        gl.glRotatef((float) heel1, 1.0f, 0.0f, 0.0f);
      else
        gl.glRotatef((float) heel2, 1.0f, 0.0f, 0.0f);
      /* gl.glTranslatef(0.0f, -0.2f, 0.0f); */
      gl.glTranslatef(0.0f, -1.7f, 0.0f);
if (LIGHT)
{
      SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess);
}
      gl.glColor3f(1.0f, 1.0f, 0.0f);
      Box(0.25f, 3.0f, 0.25f, solid);
      gl.glTranslatef(0.0f, -1.7f, 0.0f);
if (LIGHT)
{
      SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2);
}
      gl.glColor3f(0.5f, 0.5f, 0.5f);
if (SPHERE)
{
      if (!solid)
        glut.glutWireSphere(0.2f, 16, 10);
      else
        glut.glutSolidSphere(0.2f, 16, 10);
}
      if (leg != 0)
        gl.glRotatef((float) - heel1, 1.0f, 0.0f, 0.0f);
      else
        gl.glRotatef((float) - heel2, 1.0f, 0.0f, 0.0f);
      gl.glTranslatef(0.0f, -0.45f, 0.0f);
if (LIGHT)
{
      SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess);
}
      gl.glColor3f(1.0f, 1.0f, 0.0f);
      Box(1.0f, 0.5f, 1.0f, solid);
      if (k == 0 && l == 0) {
        int j;

        gl.glTranslatef(-0.4f, -0.8f, 0.5f);
        if (leg != 0)
          gl.glRotatef((float) ankle1, 1.0f, 0.0f, 0.0f);
        else
          gl.glRotatef((float) ankle2, 1.0f, 0.0f, 0.0f);
        gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
        if (!solid)
          glu.gluQuadricDrawStyle(qobj, GLU.GLU_LINE);
        glu.gluCylinder(qobj, 0.8f, 0.8f, 1.8f, 16, 10);
        for (j = 0; j < 2; j++) {
          if (!solid)
            glu.gluQuadricDrawStyle(qobj, GLU.GLU_LINE);
          if (j != 0) {
            gl.glScalef(-1.0f, 1.0f, 1.0f);
            gl.glTranslatef(0.0f, 0.0f, 1.8f);
          }
          glu.gluDisk(qobj, 0.0f, 0.8f, 16, 10);
          if (j != 0)
            gl.glTranslatef(0.0f, 0.0f, -1.8f);
        }
        gl.glScalef(-1.0f, 1.0f, 1.0f);
        gl.glRotatef(-90.0f, 0.0f, 1.0f, 0.0f);
        gl.glTranslatef(0.95f, -0.8f, 0.0f);
        gl.glCallList(SOLID_MECH_FOOT);
      }
      gl.glPopMatrix();
    }
  }
}

void
RocketPod(boolean solid)
{

  int i, j, k = 0;

  gl.glNewList(SOLID_MECH_ROCKET, GL.GL_COMPILE);
if (LIGHT)
{
  SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2);
}
  gl.glColor3f(0.5f, 0.5f, 0.5f);
  gl.glScalef(0.4f, 0.4f, 0.4f);
  gl.glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
  gl.glTranslatef(1.0f, 0.0f, 0.0f);
  Box(2.0f, 0.5f, 3.0f, solid);
  gl.glTranslatef(1.0f, 0.0f, 0.0f);
  gl.glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
  gl.glTranslatef(0.5f, 0.0f, 0.0f);
  Box(1.2f, 0.5f, 3.0f, solid);
  gl.glTranslatef(2.1f, 0.0f, 0.0f);
  gl.glRotatef(-90.0f, 0.0f, 0.0f, 1.0f);
if (LIGHT)
{
  SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess);
}
  gl.glColor3f(1.0f, 1.0f, 0.0f);
  Box(2.0f, 3.0f, 4.0f, solid);
  gl.glTranslatef(-0.5f, -1.0f, 1.3f);
  for (i = 0; i < 2; i++) {
    for (j = 0; j < 3; j++) {
      if (!solid) {
        glu.gluQuadricDrawStyle(qobj, GLU.GLU_LINE);
      }
      gl.glTranslatef(i, j, 0.6f);
if (LIGHT)
{
      SetMaterial(mat_specular3, mat_ambient3, mat_diffuse3, mat_shininess3);
}
      gl.glColor3f(1.0f, 1.0f, 1.0f);
      glu.gluCylinder(qobj, 0.4f, 0.4f, 0.3f, 16, 10);
      gl.glTranslatef(0.0f, 0.0f, 0.3f);
if (LIGHT)
{
      SetMaterial(mat_specular4, mat_ambient4, mat_diffuse4, mat_shininess4);
}
      gl.glColor3f(0.0f, 1.0f, 0.0f);
      glu.gluCylinder(qobj, 0.4f, 0.0f, 0.5f, 16, 10);
      k++;
      gl.glTranslatef(-i, -j, -0.9f);
    }
  }
  gl.glEndList();
}

void
Enviro(boolean solid)
{

  int i, j;

  gl.glNewList(SOLID_ENVIRO, GL.GL_COMPILE);
  SetMaterial(mat_specular4, mat_ambient4, mat_diffuse4, mat_shininess4);
  gl.glColor3f(0.0f, 1.0f, 0.0f);
  Box(20.0f, 0.5f, 30.0f, solid);
  SetMaterial(mat_specular4, mat_ambient3, mat_diffuse2, mat_shininess);
  gl.glColor3f(0.6f, 0.6f, 0.6f);
  gl.glTranslatef(0.0f, 0.0f, -10.0f);
  for (j = 0; j < 6; j++) {
    for (i = 0; i < 2; i++) {
      if (i != 0)
        gl.glScalef(-1.0f, 1.0f, 1.0f);
      gl.glTranslatef(10.0f, 4.0f, 0.0f);
      Box(4.0f, 8.0f, 2.0f, solid);
      gl.glTranslatef(0.0f, -1.0f, -3.0f);
      Box(4.0f, 6.0f, 2.0f, solid);
      gl.glTranslatef(-10.0f, -3.0f, 3.0f);
    }
    gl.glScalef(-1.0f, 1.0f, 1.0f);
    gl.glTranslatef(0.0f, 0.0f, 5.0f);
  }
  gl.glEndList();
}

void
Toggle()
{
  if (solid_part != 0)
    solid_part = 0;
  else
    solid_part = 1;
}

void
disable()
{
  gl.glDisable(GL.GL_LIGHTING);
  gl.glDisable(GL.GL_DEPTH_TEST);
  gl.glDisable(GL.GL_NORMALIZE);
  gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE);
}

void
lighting()
{

  float position[] =
  {0.0f, 0.0f, 2.0f, 1.0f};

if (MOVE_LIGHT)
{
  gl.glRotatef((float) lightturn1, 1.0f, 0.0f, 0.0f);
  gl.glRotatef((float) lightturn, 0.0f, 1.0f, 0.0f);
  gl.glRotatef(0.0f, 1.0f, 0.0f, 0.0f);
}
  gl.glEnable(GL.GL_LIGHTING);
  gl.glEnable(GL.GL_LIGHT0);
  gl.glEnable(GL.GL_NORMALIZE);
  gl.glDepthFunc(GL.GL_LESS);
  gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);

  gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, position, 0);
  gl.glLightf(GL.GL_LIGHT0, GL.GL_SPOT_CUTOFF, 80.0f);

  gl.glTranslatef(0.0f, 0.0f, 2.0f);
  gl.glDisable(GL.GL_LIGHTING);
  Box(0.1f, 0.1f, 0.1f, false);
  gl.glEnable(GL.GL_LIGHTING);
}

void
DrawMech()
{
  int i, j;

  gl.glScalef(0.5f, 0.5f, 0.5f);
  gl.glPushMatrix();
  gl.glTranslatef(0.0f, -0.75f, 0.0f);
  gl.glRotatef((float) tilt, 1.0f, 0.0f, 0.0f);

  gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
if (HIP)
{
  gl.glCallList(SOLID_MECH_HIP);
}
  gl.glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);

  gl.glTranslatef(0.0f, 0.75f, 0.0f);
  gl.glPushMatrix();
  gl.glRotatef((float) pivot, 0.0f, 1.0f, 0.0f);
  gl.glPushMatrix();
if (TORSO)
{
  gl.glCallList(SOLID_MECH_TORSO);
}
  gl.glPopMatrix();
  gl.glPushMatrix();
  gl.glTranslatef(0.5f, 0.5f, 0.0f);
if (ROCKET_POD)
{
  gl.glCallList(SOLID_MECH_ROCKET);
}
  gl.glPopMatrix();
  for (i = 0; i < 2; i++) {
    gl.glPushMatrix();
    if (i != 0)
      gl.glScalef(-1.0f, 1.0f, 1.0f);
    gl.glTranslatef(1.5f, 0.0f, 0.0f);
if (SHOULDER)
{
    gl.glCallList(SOLID_MECH_SHOULDER);
}
    gl.glTranslatef(0.9f, 0.0f, 0.0f);
    if (i != 0) {
      gl.glRotatef((float) lat1, 0.0f, 0.0f, 1.0f);
      gl.glRotatef((float) shoulder1, 1.0f, 0.0f, 0.0f);
      gl.glRotatef((float) shoulder3, 0.0f, 1.0f, 0.0f);
    } else {
      gl.glRotatef((float) lat2, 0.0f, 0.0f, 1.0f);
      gl.glRotatef((float) shoulder2, 1.0f, 0.0f, 0.0f);
      gl.glRotatef((float) shoulder4, 0.0f, 1.0f, 0.0f);
    }
    gl.glTranslatef(0.0f, -1.4f, 0.0f);
if (UPPER_ARM)
{
    gl.glCallList(SOLID_MECH_UPPER_ARM);
}
    gl.glTranslatef(0.0f, -2.9f, 0.0f);
    if (i != 0)
      gl.glRotatef((float) elbow1, 1.0f, 0.0f, 0.0f);
    else
      gl.glRotatef((float) elbow2, 1.0f, 0.0f, 0.0f);
    gl.glTranslatef(0.0f, -0.9f, -0.2f);
if (LOWER_ARM)
{
    gl.glCallList(SOLID_MECH_FOREARM);
    gl.glPushMatrix();
    gl.glTranslatef(0.0f, 0.0f, 2.0f);
    gl.glRotatef((float) fire, 0.0f, 0.0f, 1.0f);
    gl.glCallList(SOLID_MECH_VULCAN);
    gl.glPopMatrix();
}
    gl.glPopMatrix();
  }
  gl.glPopMatrix();

  gl.glPopMatrix();

  for (j = 0; j < 2; j++) {
    gl.glPushMatrix();
    if (j != 0) {
      gl.glScalef(-0.5f, 0.5f, 0.5f);
      leg = 1;
    } else {
      gl.glScalef(0.5f, 0.5f, 0.5f);
      leg = 0;
    }
    gl.glTranslatef(2.0f, -1.5f, 0.0f);
    if (j != 0) {
      gl.glRotatef((float) hip11, 1.0f, 0.0f, 0.0f);
      gl.glRotatef((float) hip12, 0.0f, 0.0f, 1.0f);
    } else {
      gl.glRotatef((float) hip21, 1.0f, 0.0f, 0.0f);
      gl.glRotatef((float) hip22, 0.0f, 0.0f, 1.0f);
    }
    gl.glTranslatef(0.0f, 0.3f, 0.0f);
if (UPPER_LEG)
{
    gl.glPushMatrix();
    gl.glCallList(SOLID_MECH_UPPER_LEG);
    gl.glPopMatrix();
}
    gl.glTranslatef(0.0f, -8.3f, -0.4f);
    if (j != 0)
      gl.glRotatef((float) - hip12, 0.0f, 0.0f, 1.0f);
    else
      gl.glRotatef((float) - hip22, 0.0f, 0.0f, 1.0f);
    gl.glTranslatef(-0.5f, -0.85f, -0.5f);
if (LOWER_LEG)
{
    LowerLeg(true);
}
    gl.glPopMatrix();
  }
}

public void
display()
{
  gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
  gl.glEnable(GL.GL_DEPTH_TEST);

  gl.glPushMatrix();
  gl.glRotatef((float) turn, 0.0f, 1.0f, 0.0f);
  gl.glRotatef((float) turn1, 1.0f, 0.0f, 0.0f);
if (LIGHT)
{
  if (solid_part != 0) {
    gl.glPushMatrix();
    lighting();
    gl.glPopMatrix();
  } else
    disable();
}
if (DRAW_MECH)
{
  gl.glPushMatrix();
  gl.glTranslatef(0.0f, elevation, 0.0f);
  DrawMech();
  gl.glPopMatrix();
}
if (DRAW_ENVIRO)
{
  gl.glPushMatrix();
  if (distance >= 20.136f)
    distance = 0.0f;
  gl.glTranslatef(0.0f, -5.0f, -distance);
  gl.glCallList(SOLID_ENVIRO);
  gl.glTranslatef(0.0f, 0.0f, 10.0f);
  gl.glCallList(SOLID_ENVIRO);
  gl.glPopMatrix();
}
  gl.glPopMatrix();
  gl.glFlush();
  swapBuffers();
}

void
myinit()
{
  boolean i = true;

  qobj = glu.gluNewQuadric();
if (LIGHT)
{
  SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2);
}
  gl.glEnable(GL.GL_DEPTH_TEST);
  MechTorso(i);
  MechHip(i);
  Shoulder(i);
  RocketPod(i);
  UpperArm(i);
  ForeArm(i);
  UpperLeg(i);
  Foot(i);
  VulcanGun(i);
  Enviro(i);
}

void
myReshape(int w, int h)
{
  gl.glViewport(0, 0, w, h);
  gl.glMatrixMode(GL.GL_PROJECTION);
  gl.glLoadIdentity();
  glu.gluPerspective(65.0f, (float) w / (float) h, 1.0f, 20.0f);
  gl.glMatrixMode(GL.GL_MODELVIEW);
  gl.glLoadIdentity();
  gl.glTranslatef(0.0f, 1.2f, -5.5f);  /* viewing transform  */
}

///if (ANIMATION)
///{

int step;

void
animation_walk()
{
  float angle;

  if (step == 0 || step == 2) {
    /* for(frame=3.0f; frame<=21.0f; frame=frame+3.0f){ */
    if (frame >= 0.0f && frame <= 21.0f) {
      if (frame == 0.0f)
        frame = 3.0f;
      angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));
      if (frame > 0) {
        elevation = -(3.2055f - ((float)Math.cos((M_PI / 180) * angle) * 3.2055f));
      } else
        elevation = 0.0f;
      if (step == 0) {
        hip11 = -(frame * 1.7f);
        if (1.7f * frame > 15)
          heel1 = frame * 1.7f;
        heel2 = 0;
        ankle1 = frame * 1.7f;
        if (frame > 0)
          hip21 = angle;
        else
          hip21 = 0;
        ankle2 = -hip21;
        shoulder1 = frame * 1.5f;
        shoulder2 = -frame * 1.5f;
        elbow1 = frame;
        elbow2 = -frame;
      } else {
        hip21 = -(frame * 1.7f);
        if (1.7f * frame > 15)
          heel2 = frame * 1.7f;
        heel1 = 0;
        ankle2 = frame * 1.7f;
        if (frame > 0)
          hip11 = angle;
        else
          hip11 = 0;
        ankle1 = -hip11;
        shoulder1 = -frame * 1.5f;
        shoulder2 = frame * 1.5f;
        elbow1 = -frame;
        elbow2 = frame;
      }
      if (frame == 21)
        step++;
      if (frame < 21)
        frame = frame + 3.0f;
    }
  }
  if (step == 1 || step == 3) {
    /* for(x=21.0f; x>=0.0f; x=x-3.0f){ */
    if (frame <= 21.0f && frame >= 0.0f) {
      angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2029f));
      if (frame > 0)
        elevation = -(3.2055f - ((float)Math.cos((M_PI / 180) * angle) * 3.2055f));
      else
        elevation = 0.0f;
      if (step == 1) {
        elbow2 = hip11 = -frame;
        elbow1 = heel1 = frame;
        heel2 = 15;
        ankle1 = frame;
        if (frame > 0)
          hip21 = angle;
        else
          hip21 = 0;
        ankle2 = -hip21;
        shoulder1 = 1.5f * frame;
        shoulder2 = -frame * 1.5f;
      } else {
        elbow1 = hip21 = -frame;
        elbow2 = heel2 = frame;
        heel1 = 15;
        ankle2 = frame;
        if (frame > 0)
          hip11 = angle;
        else
          hip11 = 0;
        ankle1 = -hip11;
        shoulder1 = -frame * 1.5f;
        shoulder2 = frame * 1.5f;
      }
      if (frame == 0.0f)
        step++;
      if (frame > 0)
        frame = frame - 3.0f;
    }
  }
  if (step == 4)
    step = 0;
  distance += 0.1678f;
  postRedisplay();
}


public void
animation_walkx()
{
	animation_walk0();
	animation_walk1();
	animation_walk2();
	animation_walk3();
}


boolean anim_move = true;
boolean anim_legs = false;
boolean anim_arms = true;


public void
animation_move0(int k)
{
	float frame = 3.0f * k;


	float angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));

      if (frame > 0) {
        elevation = -(3.2055f - ((float)Math.cos((M_PI / 180) * angle) * 3.2055f));
      } else
        elevation = 0.0f;

        distance += 0.1678f;
}

public void
animation_legs0(int k)
{
	float frame = 3.0f * k;


	float angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));

        hip11 = -(frame * 1.7f);
        if (1.7f * frame > 15)
          heel1 = frame * 1.7f;
        heel2 = 0;
        ankle1 = frame * 1.7f;
        if (frame > 0)
          hip21 = angle;
        else
          hip21 = 0;
        ankle2 = -hip21;
}

public void
animation_arms0(int k)
{
	float frame = 3.0f * k;


	float angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));

        shoulder1 = frame * 1.5f;
        shoulder2 = -frame * 1.5f;
        elbow1 = frame;
        elbow2 = -frame;
}


public void
animation_move1(int k)
{
	float frame = 3.0f * (7-k);


	float angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));

      if (frame > 0)
        elevation = -(3.2055f - ((float)Math.cos((M_PI / 180) * angle) * 3.2055f));
      else
        elevation = 0.0f;

        distance += 0.1678f;
}

public void
animation_legs1(int k)
{
	float frame = 3.0f * (7-k);


	float angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));

        hip11 = -frame;
        heel1 = frame;
        heel2 = 15;
        ankle1 = frame;
        if (frame > 0)
          hip21 = angle;
        else
          hip21 = 0;
        ankle2 = -hip21;
}

public void
animation_arms1(int k)
{
	float frame = 3.0f * (7-k);


	float angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));

        shoulder1 = 1.5f * frame;
        shoulder2 = -frame * 1.5f;
        elbow2 = -frame;
        elbow1 = frame;
}


public void
animation_move2(int k)
{
	float frame = 3.0f * k;


	float angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));

      if (frame > 0) {
        elevation = -(3.2055f - ((float)Math.cos((M_PI / 180) * angle) * 3.2055f));
      } else
        elevation = 0.0f;

        distance += 0.1678f;
}

public void
animation_legs2(int k)
{
	float frame = 3.0f * k;


	float angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));

        hip21 = -(frame * 1.7f);
        if (1.7f * frame > 15)
          heel2 = frame * 1.7f;
        heel1 = 0;
        ankle2 = frame * 1.7f;
        if (frame > 0)
          hip11 = angle;
        else
          hip11 = 0;
        ankle1 = -hip11;
}

public void
animation_arms2(int k)
{
	float frame = 3.0f * k;


	float angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));

        shoulder1 = -frame * 1.5f;
        shoulder2 = frame * 1.5f;
        elbow1 = -frame;
        elbow2 = frame;
}


public void
animation_move3(int k)
{
	float frame = 3.0f * (7-k);


	float angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));

      if (frame > 0)
        elevation = -(3.2055f - ((float)Math.cos((M_PI / 180) * angle) * 3.2055f));
      else
        elevation = 0.0f;

        distance += 0.1678f;
}

public void
animation_legs3(int k)
{
	float frame = 3.0f * (7-k);


	float angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));

        hip21 = -frame;
        heel2 = frame;
        heel1 = 15;
        ankle2 = frame;
        if (frame > 0)
          hip11 = angle;
        else
          hip11 = 0;
        ankle1 = -hip11;
}

public void
animation_arms3(int k)
{
	float frame = 3.0f * (7-k);


	float angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));

        shoulder1 = -frame * 1.5f;
        shoulder2 = frame * 1.5f;
        elbow1 = -frame;
        elbow2 = frame;
}





public void
animation_walk0()
{
  float angle;

    for(frame=3.0f; frame<=21.0f; frame=frame+3.0f)
    {
      if (frame == 0.0f)
        frame = 3.0f;
      angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));

if (anim_move)
{
      if (frame > 0) {
        elevation = -(3.2055f - ((float)Math.cos((M_PI / 180) * angle) * 3.2055f));
      } else
        elevation = 0.0f;

        distance += 0.1678f;
}


if (anim_legs)
{
        hip11 = -(frame * 1.7f);
        if (1.7f * frame > 15)
          heel1 = frame * 1.7f;
        heel2 = 0;
        ankle1 = frame * 1.7f;
        if (frame > 0)
          hip21 = angle;
        else
          hip21 = 0;
        ankle2 = -hip21;
}

        
if (anim_arms)
{
        shoulder1 = frame * 1.5f;
        shoulder2 = -frame * 1.5f;
        elbow1 = frame;
        elbow2 = -frame;
}        
        postRedisplay();
    }
}
  
public void
animation_walk2()
{
  float angle;

    for(frame=3.0f; frame<=21.0f; frame=frame+3.0f)
    {
      if (frame == 0.0f)
        frame = 3.0f;
      angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2059f));

if (anim_move)
{
      if (frame > 0) {
        elevation = -(3.2055f - ((float)Math.cos((M_PI / 180) * angle) * 3.2055f));
      } else
        elevation = 0.0f;

        distance += 0.1678f;
}


if (anim_legs)
{
        hip21 = -(frame * 1.7f);
        if (1.7f * frame > 15)
          heel2 = frame * 1.7f;
        heel1 = 0;
        ankle2 = frame * 1.7f;
        if (frame > 0)
          hip11 = angle;
        else
          hip11 = 0;
        ankle1 = -hip11;
}

        
if (anim_arms)
{
        shoulder1 = -frame * 1.5f;
        shoulder2 = frame * 1.5f;
        elbow1 = -frame;
        elbow2 = frame;
}        
        postRedisplay();
    }
}
  
  
public void
animation_walk1()
{
  float angle;

    for(frame=21.0f; frame>=0.0f; frame=frame-3.0f)
    {
      angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2029f));

if (anim_move)
{
      if (frame > 0)
        elevation = -(3.2055f - ((float)Math.cos((M_PI / 180) * angle) * 3.2055f));
      else
        elevation = 0.0f;

        distance += 0.1678f;
}


if (anim_legs)
{
        hip11 = -frame;
        heel1 = frame;
        heel2 = 15;
        ankle1 = frame;
        if (frame > 0)
          hip21 = angle;
        else
          hip21 = 0;
        ankle2 = -hip21;
}

        
if (anim_arms)
{
        shoulder1 = 1.5f * frame;
        shoulder2 = -frame * 1.5f;
        elbow2 = -frame;
        elbow1 = frame;
}

        postRedisplay();
    }
}
  
public void
animation_walk3()
{
  float angle;

    for(frame=21.0f; frame>=0.0f; frame=frame-3.0f)
    {
      angle = (180 / M_PI) * ((float)Math.acos((((float)Math.cos((M_PI / 180) * frame) * 2.043f) + 1.1625f) / 3.2029f));

if (anim_move)
{
      if (frame > 0)
        elevation = -(3.2055f - ((float)Math.cos((M_PI / 180) * angle) * 3.2055f));
      else
        elevation = 0.0f;

        distance += 0.1678f;
}


if (anim_legs)
{
        hip21 = -frame;
        heel2 = frame;
        heel1 = 15;
        ankle2 = frame;
        if (frame > 0)
          hip11 = angle;
        else
          hip11 = 0;
        ankle1 = -hip11;
}

        
if (anim_arms)
{
        shoulder1 = -frame * 1.5f;
        shoulder2 = frame * 1.5f;
        elbow1 = -frame;
        elbow2 = frame;
}

        postRedisplay();
    }
}



void
animation()
{
  animation_walk();
}

///}


/*


///if (GLUT)
///{
///if (GLUT_KEY)
///{

void
keyboard(char key, int x, int y)
{

  int i = 0;

  switch (key) {
    // start arm control functions
  case 'q':{
      shoulder2Subtract();
      i++;
    }
    break;
  case 'a':{
      shoulder2Add();
      i++;
    }
    break;
  case 'w':{
      shoulder1Subtract();
      i++;
    }
    break;
  case 's':{
      shoulder1Add();
      i++;
    }
    break;
  case '2':{
      shoulder3Add();
      i++;
    }
    break;
  case '1':{
      shoulder4Add();
      i++;
    }
    break;
  case '4':{
      shoulder3Subtract();
      i++;
    }
    break;
  case '3':{
      shoulder4Subtract();
      i++;
    }
    break;

  case 'z':{
      lat2Raise();
      i++;
    }
    break;
  case 'Z':{
      lat2Lower();
      i++;
    }
    break;
  case 'x':{
      lat1Raise();
      i++;
    }
    break;
  case 'X':{
      lat1Lower();
      i++;
    }
    break;

  case 'A':{
      elbow2Add();
      i++;
    }
    break;
  case 'Q':{
      elbow2Subtract();
      i++;
    }
    break;
  case 'S':{
      elbow1Add();
      i++;
    }
    break;
  case 'W':{
      elbow1Subtract();
      i++;
    }
    break;
    // end of arm control functions 

    // start of torso control functions
  case 'd':{
      RotateAdd();
      i++;
    }
    break;
  case 'g':{
      RotateSubtract();
      i++;
    }
    break;
  case 'r':{
      MechTiltAdd();
      i++;
    }
    break;
  case 'f':{
      MechTiltSubtract();
      i++;
    }
    break;
    // end of torso control functions

    // start of leg control functions
  case 'h':{
      RaiseLeg2Forward();
      i++;
    }
    break;
  case 'y':{
      LowerLeg2Backwards();
      i++;
    }
    break;
  case 'Y':{
      RaiseLeg2Outwards();
      i++;
    }
    break;
  case 'H':{
      LowerLeg2Inwards();
      i++;
    }
    break;

  case 'j':{
      RaiseLeg1Forward();
      i++;
    }
    break;
  case 'u':{
      LowerLeg1Backwards();
      i++;
    }
    break;
  case 'U':{
      RaiseLeg1Outwards();
      i++;
    }
    break;
  case 'J':{
      LowerLeg1Inwards();
      i++;
    }
    break;

  case 'N':{
      Heel2Add();
      i++;
    }
    break;
  case 'n':{
      Heel2Subtract();
      i++;
    }
    break;
  case 'M':{
      Heel1Add();
      i++;
    }
    break;
  case 'm':{
      Heel1Subtract();
      i++;
    }
    break;

  case 'k':{
      Ankle2Add();
      i++;
    }
    break;
  case 'K':{
      Ankle2Subtract();
      i++;
    }
    break;
  case 'l':{
      Ankle1Add();
      i++;
    }
    break;
  case 'L':{
      Ankle1Subtract();
      i++;
    }
    break;
    //end of leg control functions

    // start of light source position functions
  case 'p':{
      LightTurnRight();
      i++;
    }
    break;
  case 'i':{
      LightTurnLeft();
      i++;
    }
    break;
  case 'o':{
      LightForwards();
      i++;
    }
    break;
  case '9':{
      LightBackwards();
      i++;
    }
    break;
    //end of light source position functions
  }
  if (i != 0)
    glut.glutPostRedisplay();
}

///}

///if (GLUT_SPEC)
///{

void
special(int key, int x, int y)
{

  int i = 0;

  switch (key) {
    // start of view position functions
  case GLUT.GLUT_KEY_RIGHT:{
      TurnRight();
      i++;
    }
    break;
  case GLUT.GLUT_KEY_LEFT:{
      TurnLeft();
      i++;
    }
    break;
  case GLUT.GLUT_KEY_DOWN:{
      TurnForwards();
      i++;
    }
    break;
  case GLUT.GLUT_KEY_UP:{
      TurnBackwards();
      i++;
    }
    break;
    // end of view postions functions
    // start of miseclleneous functions
  case GLUT.GLUT_KEY_PAGE_UP:{
      FireCannon();
      i++;
    }
    break;
    // end of miscelleneous functions
  }
  if (i != 0)
    glut.glutPostRedisplay();
}

///}
///}

void
menu_select(int mode)
{
  switch (mode) {
///if (ANIMATION)
///{
  case 1:
    glut.glutIdleFunc(animation);
    break;
///}
  case 2:
    glut.glutIdleFunc(NULL);
    break;
  case 3:
    Toggle();
    glut.glutPostRedisplay();
    break;
  case 4:
    System.exit();
  }
}


void
null_select(int mode)
{
}

void
glutMenu()
{

  int glut_menu[] = new int[13];

  glut_menu[5] = glut.glutCreateMenu(null_select);
  glut.glutAddMenuEntry("forward       : q,w", 0);
  glut.glutAddMenuEntry("backwards     : a,s", 0);
  glut.glutAddMenuEntry("outwards      : z,x", 0);
  glut.glutAddMenuEntry("inwards       : Z,X", 0);

  glut_menu[6] = glut.glutCreateMenu(null_select);
  glut.glutAddMenuEntry("upwards       : Q,W", 0);
  glut.glutAddMenuEntry("downwards     : A,S", 0);
  glut.glutAddMenuEntry("outwards      : 1,2", 0);
  glut.glutAddMenuEntry("inwards       : 3,4", 0);

  glut_menu[1] = glut.glutCreateMenu(null_select);
  glut.glutAddMenuEntry(" : Page_up", 0);

  glut_menu[8] = glut.glutCreateMenu(null_select);
  glut.glutAddMenuEntry("forward       : y,u", 0);
  glut.glutAddMenuEntry("backwards     : h.j", 0);
  glut.glutAddMenuEntry("outwards      : Y,U", 0);
  glut.glutAddMenuEntry("inwards       : H,J", 0);

  glut_menu[9] = glut.glutCreateMenu(null_select);
  glut.glutAddMenuEntry("forward       : n,m", 0);
  glut.glutAddMenuEntry("backwards     : N,M", 0);

  glut_menu[9] = glut.glutCreateMenu(null_select);
  glut.glutAddMenuEntry("forward       : n,m", 0);
  glut.glutAddMenuEntry("backwards     : N,M", 0);

  glut_menu[10] = glut.glutCreateMenu(null_select);
  glut.glutAddMenuEntry("toes up       : K,L", 0);
  glut.glutAddMenuEntry("toes down     : k,l", 0);

  glut_menu[11] = glut.glutCreateMenu(null_select);
  glut.glutAddMenuEntry("right         : right arrow", 0);
  glut.glutAddMenuEntry("left          : left arrow", 0);
  glut.glutAddMenuEntry("down          : up arrow", 0);
  glut.glutAddMenuEntry("up            : down arrow", 0);

  glut_menu[12] = glut.glutCreateMenu(null_select);
  glut.glutAddMenuEntry("right         : p", 0);
  glut.glutAddMenuEntry("left          : i", 0);
  glut.glutAddMenuEntry("up            : 9", 0);
  glut.glutAddMenuEntry("down          : o", 0);

  glut_menu[4] = glut.glutCreateMenu(NULL);
  glut.glutAddSubMenu("at the shoulders? ", glut_menu[5]);
  glut.glutAddSubMenu("at the elbows?", glut_menu[6]);

  glut_menu[7] = glut.glutCreateMenu(NULL);
  glut.glutAddSubMenu("at the hip? ", glut_menu[8]);
  glut.glutAddSubMenu("at the knees?", glut_menu[9]);
  glut.glutAddSubMenu("at the ankles? ", glut_menu[10]);

  glut_menu[2] = glut.glutCreateMenu(null_select);
  glut.glutAddMenuEntry("turn left    : d", 0);
  glut.glutAddMenuEntry("turn right    : g", 0);

  glut_menu[3] = glut.glutCreateMenu(null_select);
  glut.glutAddMenuEntry("tilt backwards : f", 0);
  glut.glutAddMenuEntry("tilt forwards  : r", 0);

  glut_menu[0] = glut.glutCreateMenu(NULL);
  glut.glutAddSubMenu("move the arms.. ", glut_menu[4]);
  glut.glutAddSubMenu("fire the vulcan guns?", glut_menu[1]);
  glut.glutAddSubMenu("move the legs.. ", glut_menu[7]);
  glut.glutAddSubMenu("move the torso?", glut_menu[2]);
  glut.glutAddSubMenu("move the hip?", glut_menu[3]);
  glut.glutAddSubMenu("rotate the scene..", glut_menu[11]);
if (MOVE_LIGHT)
{
  glut.glutAddSubMenu("rotate the light source..", glut_menu[12]);
}

  glut.glutCreateMenu(menu_select);
if (ANIMATION)
{
  glut.glutAddMenuEntry("Start Walk", 1);
  glut.glutAddMenuEntry("Stop Walk", 2);
}
  glut.glutAddMenuEntry("Toggle Wireframe", 3);
  glut.glutAddSubMenu("How do I ..", glut_menu[0]);
  glut.glutAddMenuEntry("Quit", 4);
  glut.glutAttachMenu(GLUT.GLUT_LEFT_BUTTON);
  glut.glutAttachMenu(GLUT.GLUT_RIGHT_BUTTON);
}

void 
mymain(String args[])
{
if (GLUT)
{
  // start of glut windowing and control functions
  glut.glutInit(args);
  glut.glutInitDisplayMode(GLUT.GLUT_DOUBLE | GLUT.GLUT_RGBA | GLUT.GLUT_DEPTH);
  glut.glutInitWindowSize(800, 600);
  glut.glutCreateWindow("glutmech: Vulcan Gunner");
  myinit();
  glut.glutDisplayFunc(display);
  glut.glutReshapeFunc(myReshape);
if (GLUT_KEY)
{
  glut.glutKeyboardFunc(keyboard);
}
if (GLUT_SPEC)
{
  glut.glutSpecialFunc(special);
}
  glut.glutMenu();
  glut.glutMainLoop();
  // end of glut windowing and control functions
}
}

*/


GLDrawable drawable;

public void swapBuffers()
{
	drawable.swapBuffers();
}

public void postRedisplay()
{
	display();
}


public void mysetup()
{
	JFrame frame = new JFrame("Model Displayer");

	STGLCanvas canvas = new STGLCanvas();
	frame.add(canvas);

	frame.setLocation(200, 0);
	frame.setSize(800, 600);
	frame.setVisible(true);
	
	GLContext context = canvas.getContext();
	drawable = canvas.getDrawable();
	
	context.makeCurrent();
	
	gl = context.getGL();
	glu = new GLU();
	glut = new GLUT();
	
	solid_part = 1;
	
	myinit();
	myReshape(800, 600);
}




public void mymain()
{
	Thread thread = new Thread(new Runnable()
	{
		public void run()
		{
			mysetup();
			
			for (;;)
			{
				animation_walkx();
			}
		}
	});
	
	thread.start();
}




public static void 
main(String args[])
{
	TestMech m = new TestMech();
	
	m.mymain();
}

}